package com.zcxy.sys.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zcxy.constant.CommonConstant;
import com.zcxy.core.bean.PageQuery;
import com.zcxy.mybatis.bean.SysUser;
import com.zcxy.mybatis.service.BaseServiceImpl;
import com.zcxy.mybatis.util.RelationHelper;
import com.zcxy.sys.constant.Constant;
import com.zcxy.sys.entity.*;
import com.zcxy.sys.mapper.SysRoleMapper;
import com.zcxy.sys.pojo.SysRoleVo;
import com.zcxy.sys.service.ISysRoleService;
import com.zcxy.sys.service.ISysRoleUserService;
import com.zcxy.util.BeanCopierUtil;
import com.zcxy.util.FileUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 角色Service业务层处理
 *
 * @author zcc
 * @email 860474958@qq.com
 * @date 2020-06-02
 */
@Service
@Slf4j
public class SysRoleServiceImpl extends BaseServiceImpl<SysRoleMapper, SysRole>
        implements ISysRoleService {

    @Autowired
    private ISysRoleUserService sysRoleUserMapper;



    @Override
    @Transactional(rollbackFor = Exception.class)
    public IPage<SysRoleVo> queryPageList(PageQuery<SysRole> queryVo) {
        QueryWrapper queryWrapper = new QueryWrapper();
        if (queryVo.getT() != null && !StringUtils.isEmpty(queryVo.getT().getRoleName())) {
            queryWrapper.like("role_name", queryVo.getT().getRoleName());
        }
        if (queryVo.getT() != null && !StringUtils.isEmpty(queryVo.getT().getStatus())) {
            queryWrapper.eq("status", queryVo.getT().getStatus());
        }
        Page page = new Page(queryVo.getPageNo(), queryVo.getPageSize());
        IPage<SysRole> sysUserVoIPage = baseMapper.selectPage(page, queryWrapper);
        return BeanCopierUtil.copyPage(sysUserVoIPage, SysRoleVo.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<SysRoleVo> queryList() {
        SysRole queryVo = new SysRole();
        queryVo.setStatus(Constant.ENABLE);
        QueryWrapper queryWrapper = new QueryWrapper(queryVo);
        List<SysRole> sysRoles = baseMapper.selectList(queryWrapper);
        return BeanCopierUtil.copyListToList(sysRoles, SysRoleVo.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addSysRole(SysRole queryVo) {
        validFiledExistInsert("roleName", queryVo.getRoleName(), "角色名称已经存在请勿重复");
        validFiledExistInsert("code", queryVo.getCode(), "唯一编码已经存在请勿重复");
        queryVo.setDelFlag(CommonConstant.DEL_FLAG_1);
        //TODO 具体新增业务限制各自实现
        baseMapper.insert(queryVo);
        addSysRoleUser(queryVo.getUserIds(), queryVo.getId());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addSysRoleUser(List<String> userIds, String roleId) {
        if (CollectionUtil.isEmpty(userIds)) {
            return;
        }
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("role_id", roleId);
        sysRoleUserMapper.getBaseMapper().delete(queryWrapper);
        List<SysRoleUser> sysRoleUsers = new ArrayList<>();
        userIds.stream().forEach(i -> {
            SysRoleUser sysRoleUser = new SysRoleUser();
            sysRoleUser.setRoleId(roleId);
            sysRoleUser.setUserId(i);
            sysRoleUsers.add(sysRoleUser);

        });
        sysRoleUserMapper.saveBatch(sysRoleUsers);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateSysRole(SysRole queryVo) {
        //查询数据库的实体(主键校验在controller的校验器里面)
        SysRole sysRoleDb = baseMapper.selectById(queryVo.getId());
        BeanCopierUtil.copyObject(queryVo, sysRoleDb);
        baseMapper.updateById(sysRoleDb);
        addSysRoleUser(queryVo.getUserIds(), queryVo.getId());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeSysRole(String id) {
        baseMapper.deleteById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeAllSysRole(List<String> ids) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.in("id", ids);
        baseMapper.delete(queryWrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void download(SysRole queryVo, HttpServletResponse response) throws IOException {
        List<SysRole> sysRoles = baseMapper.selectList(new QueryWrapper<>(queryVo));
        List<Map<String, Object>> list = new ArrayList<>();
        for (SysRole sysRoleExcel : sysRoles) {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("主键", sysRoleExcel.getId());
            map.put("角色名称", sysRoleExcel.getRoleName());
            map.put("描述", sysRoleExcel.getDescription());
            map.put("启用(0未启用1启用)", sysRoleExcel.getStatus());
            map.put("全部工作区（0非全工作区，1全工作区）", sysRoleExcel.getUsedAllworkspace());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public SysRoleVo viewSysRole(String id) {

        SysRole sysRole = baseMapper.selectById(id);
        SysRoleVo sysRoleVo = BeanCopierUtil.copyObject(sysRole, SysRoleVo.class);
        RelationHelper.render(sysRoleVo);
        List<SysUser> sysUsers = sysRoleVo.getUsers();
        if (CollectionUtil.isNotEmpty(sysUsers)) {
            sysRoleVo.setUserIds(sysUsers.stream().map(SysUser::getId).collect(Collectors.toList()));
        }


        return sysRoleVo;
    }

}
